package co.edu.uniandes.ecos.itera.tsp.interfaz;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Set;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;

import co.edu.uniandes.ecos.itera.tsp.anotaciones.Loc;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.LogT;
import co.edu.uniandes.ecos.itera.tsp.anotaciones.Tiempos;
import co.edu.uniandes.ecos.itera.tsp.mundo.Ciclo;
import co.edu.uniandes.ecos.itera.tsp.mundo.DelegadoNegocio;
import co.edu.uniandes.ecos.itera.tsp.mundo.Desarrollador;
import co.edu.uniandes.ecos.itera.tsp.mundo.EntidadReporteCalidad;
import co.edu.uniandes.ecos.itera.tsp.mundo.Etapa;

/**
 * Permite invocar la generacion del reporte por el ciclo del proyecto
 * seleccionado.
 * 
 * @author ojato
 * 
 */
@Tiempos( { @LogT(date = "2011-03-20", min = 109, taskId = 130) })
public class ReporteCalidad extends JPanel implements ActionListener {
	/**
	 * Etiquetas necesarias para la interfaz
	 */
	private JLabel labelTitulo, labelNombreProyecto, labelNnombreGrupo,
			labelDetalleGrupo, labelEstimado, labelReal, labelTotal,
			labelDetalleXDes;
	/**
	 * Panel que contiene los titulos de la pantalla
	 */
	private JPanel panelTitulo;
	/**
	 * Panel para el detalle de inyecion y remosion del grupo indicando el total
	 * de defectos por k loc
	 */
	private JPanel panelDetalleGrupo;
	/**
	 * Tabla que contiene la informacion de reporte por grupo
	 */
	private JTable tablaDetalleGrupo;
	/**
	 * Ttal de defectos por mil lineas de codigo para el grupo
	 */
	private JTextField defKlocXGrupo;
	/**
	 * Panel para el detalle por desarollador
	 */
	private JPanel panelDetalleDes;
	/**
	 * Referencia al objeto que permite trabajar las transacciones de negocio
	 */
	private DelegadoNegocio accesoAMundo;
	/**
	 * Referencia al objeto contenedor. Este es el objeto que maneja la pantalla
	 * principal, o sea el admon de proyectos
	 */
	private MenuPrincipal referenciaAContenedor;
	/**
	 * Ciclo para el cual se esta ejecutando el reporte.
	 */
	private Ciclo ciclo;
	/**
	 * Reporte ejecuta y que se desea mostrar
	 */
	private EntidadReporteCalidad reporte;

	@Tiempos( { @LogT(date = "2011-03-26", min = 29, taskId = 124) })
	public ReporteCalidad(DelegadoNegocio mundo, MenuPrincipal contenedor,
			Ciclo ciclo) {
		this.accesoAMundo = mundo;
		this.referenciaAContenedor = contenedor;

		this.ciclo = ciclo;
		this.pintarse();
	}

	/**
	 * Dibuja el reporte solicitado.
	 */
	@Loc(size = 32, taskId = 130)
	private void pintarse() {
		setLayout(new GridLayout(4, 2));
		setPreferredSize(new Dimension(400, 200));
		/*
		 * Incluye las tiquetas para el titulo de la pantalla
		 */
		this.panelTitulo = new JPanel();
		this.panelTitulo.setLayout(new GridLayout(2, 1));
		this.labelTitulo = new JLabel("Reporte De Calidad");
		this.labelNnombreGrupo = new JLabel("i-Tera");
		this.panelTitulo.add(labelTitulo);
		this.panelTitulo.add(labelNnombreGrupo);
		/*
		 * Contiene la tabla inyectado vs real del grupo
		 */
		this.panelDetalleGrupo = new JPanel();
		this.panelDetalleGrupo.setLayout(new GridLayout(2, 1));

		// ejecuta el reporte para alimentar las tablas:

		reporte = this.accesoAMundo.generarReporteCalidad(this.ciclo);

		// alimenta el resumen por grupo
		JPanel resultados = ejecutarReporteXGrupo();
		if (resultados != null) {
			this.panelDetalleGrupo.add(resultados);

		} else {
			JLabel error = new JLabel(
					"No se ha cargado la información del Grupo");
			this.panelDetalleGrupo.add(error);

		}
		// alimenta el resumen por desarrollador.
		this.panelDetalleDes = new JPanel();
		this.panelDetalleDes.setLayout(new GridLayout(2, 1));
		JPanel resultadosDes = ejecutarReporteXDesarrollador();
		if (resultadosDes != null) {
			this.panelDetalleDes.add(resultadosDes);

		} else {
			JLabel error = new JLabel(
					"No se ha cargado la información de los desarrolladores");
			this.panelDetalleDes.add(error);

		}

		add(panelTitulo);
		add(panelDetalleGrupo);
		add(panelDetalleDes);

	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub

	}

	/**
	 * Alimenta la tabla que contendra el reporte por Grupo
	 * 
	 * @return el panel que sera ubicado en el contendor para el resumen del
	 *         grupo
	 */
	@Loc(size = 96, taskId = 130)
	private JPanel ejecutarReporteXGrupo() {
		if (reporte != null) {
			JPanel resultados = new JPanel();
			resultados.setLayout(new GridLayout(2, 1));

			JPanel resumen = new JPanel();
			resumen.setLayout(new GridLayout(1, 2));
			this.labelTotal = new JLabel("Defectos X KLOC Por Grupo: ");
			this.defKlocXGrupo = new JTextField();

			Hashtable<Etapa, Integer> inyectados = reporte
					.getTotalDefectosInyectadosXGrupo();
			Hashtable<Etapa, Integer> removidos = reporte
					.getTotalDefectosXGrupo();

			String[] titulos = { "Etapa", "Inyectados", "Removidos" };
			String[][] data = new String[7][3];
			int totalInyectadosReales = 0;
			data[0][0] = "ESTRATEGIA";
			data[0][1] = inyectados != null
					&& inyectados.get(Etapa.ESTRATEGIA) != null ? Integer
					.toString(inyectados.get(Etapa.ESTRATEGIA)) : "0";
			data[0][2] = removidos != null
					&& removidos.get(Etapa.ESTRATEGIA) != null ? Integer
					.toString(removidos.get(Etapa.ESTRATEGIA)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.ESTRATEGIA) != null) ? inyectados
					.get(Etapa.ESTRATEGIA) : 0;

			data[1][0] = "PLANEACIÓN";
			data[1][1] = inyectados != null
					&& inyectados.get(Etapa.PLANEACION) != null ? Integer
					.toString(inyectados.get(Etapa.PLANEACION)) : "0";
			data[1][2] = removidos != null
					&& removidos.get(Etapa.PLANEACION) != null ? Integer
					.toString(removidos.get(Etapa.PLANEACION)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.PLANEACION) != null) ? inyectados
					.get(Etapa.PLANEACION) : 0;

			data[2][0] = "DISEÑO";
			data[2][1] = inyectados != null
					&& inyectados.get(Etapa.DISENO) != null ? Integer
					.toString(inyectados.get(Etapa.DISENO)) : "0";
			data[2][2] = removidos != null
					&& removidos.get(Etapa.DISENO) != null ? Integer
					.toString(removidos.get(Etapa.DISENO)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.DISENO) != null) ? inyectados.get(Etapa.DISENO)
					: 0;

			data[3][0] = "DESARROLLO";
			data[3][1] = inyectados != null
					&& inyectados.get(Etapa.DESARROLLO) != null ? Integer
					.toString(inyectados.get(Etapa.DESARROLLO)) : "0";
			data[3][2] = removidos != null
					&& removidos.get(Etapa.DESARROLLO) != null ? Integer
					.toString(removidos.get(Etapa.DESARROLLO)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.DESARROLLO) != null) ? inyectados
					.get(Etapa.DESARROLLO) : 0;

			data[4][0] = "REVISION";
			data[4][1] = inyectados != null
					&& inyectados.get(Etapa.INSPECCION) != null ? Integer
					.toString(inyectados.get(Etapa.INSPECCION)) : "0";
			data[4][2] = removidos != null
					&& removidos.get(Etapa.INSPECCION) != null ? Integer
					.toString(removidos.get(Etapa.INSPECCION)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.INSPECCION) != null) ? inyectados
					.get(Etapa.INSPECCION) : 0;

			data[5][0] = "PRUEBAS";
			data[5][1] = inyectados != null
					&& inyectados.get(Etapa.PRUEBAS) != null ? Integer
					.toString(inyectados.get(Etapa.PRUEBAS)) : "0";
			data[5][2] = removidos != null
					&& removidos.get(Etapa.PRUEBAS) != null ? Integer
					.toString(removidos.get(Etapa.PRUEBAS)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.PRUEBAS) != null) ? inyectados
					.get(Etapa.PRUEBAS) : 0;

			data[6][0] = "POSTMORTEM";
			data[6][1] = inyectados != null
					&& inyectados.get(Etapa.POSTMORTEM) != null ? Integer
					.toString(inyectados.get(Etapa.POSTMORTEM)) : "0";
			data[6][2] = removidos != null
					&& removidos.get(Etapa.POSTMORTEM) != null ? Integer
					.toString(removidos.get(Etapa.POSTMORTEM)) : "0";
			totalInyectadosReales += (inyectados != null && inyectados
					.get(Etapa.POSTMORTEM) != null) ? inyectados
					.get(Etapa.POSTMORTEM) : 0;

			/*
			 * calcular total de defectos
			 */
			int totalLineas = reporte.getTotalLineasCodigoGrupo();
			int relacionDefectKLOC = totalLineas > 0 ? (1000 * totalInyectadosReales)
					/ totalLineas
					: 0;
			defKlocXGrupo.setText(((Integer) relacionDefectKLOC).toString());
			resumen.add(labelTotal);
			resumen.add(defKlocXGrupo);
			resultados.add(new JTable(data, titulos));
			resultados.add(resumen);

			return resultados;

		}
		return null;

	}

	/**
	 * Alimenta la tabla para el detalle por desarrollador.
	 * 
	 * @return el panel que se ubicara en la zona de resumen por desarrollador.
	 */
	@Loc(size = 127, taskId = 130)
	private JPanel ejecutarReporteXDesarrollador() {
		if (reporte != null) {
			JPanel resultados = new JPanel();
			resultados.setLayout(new GridLayout(1, 1));

			Hashtable<Desarrollador, Hashtable<Etapa, Integer>> inyectados = reporte
					.getTotalDefectosInyectadosXDesarrollador();
			Hashtable<Desarrollador, Hashtable<Etapa, Integer>> removidos = reporte
					.getTotalDefectosXDesarrollador();

			String[] titulos = { "FASE/DES", "ESTRATEGIA INY",
					"PLANEACIÓN INY", "DISEÑO INY", "DESARROLLO INY",
					"INSPECCIÓN INY ", "PRUEBAS INY", "POSTMORTEM INY",
					"ESTRATEGIA REM", "PLANEACIÓN REM", "DISEÑO REM",
					"DESARROLLO REM", "INSPECCIÓN REM ", "PRUEBAS REM",
					"POSTMORTEM REM", "DEFKLOC" };
			String[][] data = null;
			if (inyectados != null) {

				Set<Desarrollador> desarrolladores = inyectados.keySet();
				if (desarrolladores.size() > 0) {
					data = new String[desarrolladores.size()][16];
					int contDes = 0;
					Hashtable<Desarrollador, Integer> lineasDes = reporte
							.getTotalLineasDesarrollador();
					for (Desarrollador desarrollador : desarrolladores) {
						int totalDefDes = 0;
						Hashtable<Etapa, Integer> inyDes = inyectados
								.get(desarrollador);
						Hashtable<Etapa, Integer> remDes = removidos
								.get(desarrollador);
						data[contDes][0] = desarrollador.getNombre();
						data[contDes][1] = inyDes != null
								&& inyDes.get(Etapa.ESTRATEGIA) != null ? Integer
								.toString(inyDes.get(Etapa.ESTRATEGIA))
								: "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.ESTRATEGIA) != null ? inyDes
								.get(Etapa.ESTRATEGIA)
								: 0;
						data[contDes][2] = inyDes != null
								&& inyDes.get(Etapa.PLANEACION) != null ? Integer
								.toString(inyDes.get(Etapa.PLANEACION))
								: "0";

						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.PLANEACION) != null ? inyDes
								.get(Etapa.PLANEACION)
								: 0;

						data[contDes][3] = inyDes != null
								&& inyDes.get(Etapa.DISENO) != null ? Integer
								.toString(inyDes.get(Etapa.DISENO)) : "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.DISENO) != null ? inyDes
								.get(Etapa.DISENO) : 0;

						data[contDes][4] = inyDes != null
								&& inyDes.get(Etapa.DESARROLLO) != null ? Integer
								.toString(inyDes.get(Etapa.DESARROLLO))
								: "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.DESARROLLO) != null ? inyDes
								.get(Etapa.DESARROLLO)
								: 0;

						data[contDes][5] = inyDes != null
								&& inyDes.get(Etapa.INSPECCION) != null ? Integer
								.toString(inyDes.get(Etapa.INSPECCION))
								: "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.INSPECCION) != null ? inyDes
								.get(Etapa.INSPECCION)
								: 0;

						data[contDes][6] = inyDes != null
								&& inyDes.get(Etapa.PRUEBAS) != null ? Integer
								.toString(inyDes.get(Etapa.PRUEBAS)) : "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.PRUEBAS) != null ? inyDes
								.get(Etapa.PRUEBAS) : 0;

						data[contDes][7] = inyDes != null
								&& inyDes.get(Etapa.POSTMORTEM) != null ? Integer
								.toString(inyDes.get(Etapa.POSTMORTEM))
								: "0";
						totalDefDes += inyDes != null
								&& inyDes.get(Etapa.POSTMORTEM) != null ? inyDes
								.get(Etapa.POSTMORTEM)
								: 0;

						data[contDes][8] = remDes != null
								&& remDes.get(Etapa.ESTRATEGIA) != null ? Integer
								.toString(remDes.get(Etapa.ESTRATEGIA))
								: "0";
						data[contDes][9] = remDes != null
								&& remDes.get(Etapa.PLANEACION) != null ? Integer
								.toString(remDes.get(Etapa.PLANEACION))
								: "0";
						data[contDes][10] = remDes != null
								&& remDes.get(Etapa.DISENO) != null ? Integer
								.toString(remDes.get(Etapa.DISENO)) : "0";

						data[contDes][11] = remDes != null
								&& remDes.get(Etapa.DESARROLLO) != null ? Integer
								.toString(remDes.get(Etapa.DESARROLLO))
								: "0";
						data[contDes][12] = remDes != null
								&& remDes.get(Etapa.INSPECCION) != null ? Integer
								.toString(remDes.get(Etapa.INSPECCION))
								: "0";
						data[contDes][13] = remDes != null
								&& remDes.get(Etapa.PRUEBAS) != null ? Integer
								.toString(remDes.get(Etapa.PRUEBAS)) : "0";

						data[contDes][14] = remDes != null
								&& remDes.get(Etapa.POSTMORTEM) != null ? Integer
								.toString(remDes.get(Etapa.POSTMORTEM))
								: "0";

						int relacionDefKLOC = 0;
						if (lineasDes != null) {
							if (lineasDes.get(desarrollador) != null) {
								int lineas = lineasDes.get(desarrollador);
								relacionDefKLOC = lineas > 0 ? 1000
										* totalDefDes / lineas : 0;
							}
						}
						data[contDes][15] = Integer.toString(relacionDefKLOC);

						contDes++;
					}
				}
			}
			if (data != null) {

				JTable detalle = new JTable(data, titulos);
				resultados.add(detalle);

				return resultados;
			}
		}

		return null;
	}

}
